import cloud from '@lafjs/cloud'
import Pay from 'wechatpay-node-v3-laf';
import { changeStudentSource } from "@/admin/web/set_student_info";
import { changeOrderInfo } from "@/admin/web/set_order_info";
import { setUserInfo } from "@/thirdParty/moxueyuanUtils";
import { setOrderLearningStatus } from "@/admin/web/set_order_info";

let appid
let data
let out_refund_no //退款单号

export default async function (ctx: FunctionContext) {
  out_refund_no = generateOrderNumber()
  data = ctx.body

  if (ctx.body.payType == "MP-WEIXIN") {
    appid = "wx9c3827b9e4e2ea96"
  } else {
    appid = "wx267097d752f5c3fd"
  }

  const pay = new Pay({
    appid, // 认证服务号 appid
    mchid: '1593154581',  //  绑定该认证服务号的微信支付商户号
    publicKey: savePublicKey(), // V3 公钥 apiclient_cert.pem
    privateKey: savePrivateKey(), // V3 秘钥 apiclient_key.pem
  });

  //优惠减免
  if (data.discountPrice) return await discountRefund(pay)

  //优惠减免过的退款
  if (data.changeOrderStatus) return await customRefund(pay)

  //尾款退款
  if (data.balance_out_trade_no) {
    if (!data.out_trade_no) {
      return await balanceRefund(pay, data.balance_out_trade_no)
    }
    balanceRefund(pay, data.balance_out_trade_no)
  }

  //第一笔支付的退款
  const params = {
    out_trade_no: data.out_trade_no,
    out_refund_no,//退款单号
    reason: '支付退款',
    amount: {
      refund: ctx.body.amount,
      total: ctx.body.amount,
      currency: 'CNY',
    },
  };

  let refundResult = await pay.refunds(params);
  if (refundResult.status == "PROCESSING") {
    const ret = await pay.find_refunds(out_refund_no);
    console.log("查询退款", ret);
    if (ret.status == "PROCESSING") {//退款成功
      await cloud.nw.db.update({
        dbName: "web-order",
        whereJson: { out_trade_no: ret.out_trade_no }, //单号去查
        dataJson: { //更新订单
          refund_info: {
            out_refund_no,
            refund_time: ret.create_time,
            refund_amount: ret.amount,  //单位是分，前端展示的时候要/100
            refund_id: ret.refund_id,
            transaction_id: ret.transaction_id,
            user_received_account: ret.user_received_account,
            updateUser: ctx.body.updateUser, //操作退款的人
            refundReason: ctx.body.refundReason,//退款原因
          },
          status: 4,
        },
      });
      await setOrderStatus({ out_trade_no: ret.out_trade_no })
      //修改魔学院标签信息
      await changeStudentSource(ret.out_trade_no)
      await changeOrderInfo({ out_trade_no: ret.out_trade_no })
      return cloud.utils.requestReturn({ data: "退款成功" })
    } else {
      return cloud.utils.requestReturn({ code: 500, msg: ret.message })
    }
  } else if (refundResult.errRaw && refundResult.errRaw.status == "403") {
    //退款失败
    return cloud.utils.requestReturn({ code: 500, msg: `退款失败，请检查是否有退款权限或余额是否足够` })
  }
}

async function setOrderStatus(whereJson) {
  let res = await cloud.nw.db.findByWhereJson({
    dbName: "web-order",
    whereJson,
  });
  let isAllRefund = false
  //如果有优惠减免
  if (res.pay_discount_info) {
    let total = 0 //订单总支付
    if (res.pay_info) total += res.pay_info.pay_amount.total
    if (res.pay_discount_info) total += res.balance_pay_info.pay_amount.total

    let discountTotal = 0 //优惠减免的总金额
    res.pay_discount_info.forEach(element => {
      discountTotal += element.info.amount.refund
    });

    let refundTotal = 0 //退款的总金额
    if (res.refund_info) refundTotal += res.refund_info.refund_amount.refund
    if (res.balance_refund_info) refundTotal += res.balance_refund_info.refund_amount.refund
    let finalAmount = total - discountTotal - refundTotal //最终支付的金额
    if (finalAmount == 0) isAllRefund = true
  } else {
    //如果有尾款支付
    if (res.balance_out_trade_no) {
      if (res.hasOwnProperty('balance_refund_info') && res.hasOwnProperty('refund_info')) {
        isAllRefund = true
      }
    } else if (res.hasOwnProperty('refund_info')) {
      isAllRefund = true
    }
  }

  await cloud.nw.db.update({
    dbName: "web-order",
    whereJson, //单号去查
    dataJson: { //更新订单
      status: isAllRefund ? 4 : 9, //全部退款成功，订单状态4：,
    },
  });
}

//优惠减免退款
async function discountRefund(pay) {
  let out_trade_no = data.out_trade_no || data.balance_out_trade_no
  const params = {
    out_trade_no,
    out_refund_no,
    reason: data.discountReason || '优惠减免',
    amount: {
      refund: Number(data.discountPrice),
      total: Number(data.total),
      currency: 'CNY',
    },
  };
  const result = await pay.refunds(params);
  console.log("优惠减免退款的结果", result);
  //失败
  if (result.hasOwnProperty("errRaw")) {
    //如果退款失败，则删除对应的优惠减免记录
    await cloud.nw.db.del({ dbName: "order-discount-record", whereJson: { discountUid: data.discountUid } });
    wxPayrecordError("refunds", result)

    return cloud.utils.requestReturn({ code: 500, msg: "退款失败，请检查是否有退款权限或余额是否足够" })
  } else {
    const resDiscount = await pay.find_refunds(out_refund_no);
    console.log("查询退款", resDiscount);
    if (resDiscount.status == "PROCESSING") {//退款成功
      let whereJson = { _id: data.orderId }
      let key = data.out_trade_no ? "out_trade_no" : "balance_out_trade_no"
      let ret = await cloud.nw.db.findByWhereJson({
        dbName: "web-order", whereJson,
      });
      let pay_discount_info = ret.pay_discount_info || []
      let query = {
        discountUid: data.discountUid,
        out_refund_no,
        info: {
          create_time: resDiscount.create_time,
          amount: resDiscount.amount,  //单位是分，前端展示的时候要/100
          refund_id: resDiscount.refund_id,
          transaction_id: resDiscount.transaction_id,
          user_received_account: resDiscount.user_received_account,
          updateUser: data.updateUser, //操作退款的人
          discountReason: data.discountReason,//退款原因
        }
      }
      //下单的单号的字段可以
      query[key] = out_trade_no
      pay_discount_info.push(query)
      //更新订单金额
      await changeOrderInfo(whereJson)
      //更新订单
      await cloud.nw.db.update({
        dbName: "web-order",
        whereJson, //单号去查
        dataJson: { pay_discount_info },
      });
      updateMoXueYuanInfo(data)
      return cloud.utils.requestReturn({ data: "优惠减免成功" })
    } else {
      return cloud.utils.requestReturn({ code: 500, msg: resDiscount.message })
    }
  }
}

//优惠成功，操作学员新课程标签
async function updateMoXueYuanInfo(data) {
  let res = await cloud.utils.findData("order-discount-record", { discountUid: data.discountUid })
  console.log("获取到魔学院编辑的信息", res.data)
  //修改魔学院信息
  await setUserInfo(res.data.editMoxueyuanInfo)
  setOrderLearningStatus()//重新生成一次中间页
}


//自定义退款
async function customRefund(pay) {
  const params = {
    out_trade_no: data.out_trade_no,
    out_refund_no,
    reason: '订单退款',
    amount: {
      refund: data.refund,
      total: data.total,
      currency: 'CNY',
    },
  };
  const result = await pay.refunds(params);
  //失败
  if (result.hasOwnProperty("errRaw")) {
    wxPayrecordError("refunds", result)
    return cloud.utils.requestReturn({ code: 500, msg: "退款失败，请检查是否有退款权限或余额是否足够" })
  } else {
    const ret = await pay.find_refunds(out_refund_no);
    let obj = {
      out_refund_no,
      refund_time: ret.create_time,
      refund_amount: ret.amount,  //单位是分，前端展示的时候要/100
      refund_id: ret.refund_id,
      transaction_id: ret.transaction_id,
      user_received_account: ret.user_received_account,
      updateUser: data.updateUser, //操作退款的人
      refundReason: data.refundReason,//退款原因
    }
    let dataJson = {}
    dataJson[data.key == "out_trade_no" ? "refund_info" : "balance_refund_info"] = obj
    await cloud.nw.db.update({
      dbName: "web-order",
      whereJson: { _id: data.orderId },
      dataJson
    });
    await changeOrderInfo({ _id: data.orderId })
    await setOrderStatus({ _id: data.orderId })
    return cloud.utils.requestReturn({ data: "退款成功" })
  }
}

//记录微信支付报错
async function wxPayrecordError(type, resp) {
  let now = Date.now()
  await cloud.nw.db.add({
    dbName: "wx-pay-error",
    dataJson: {
      type,
      content: resp,
      timeStamp: now,
      timeUTC8_format: cloud.utils.dateTimeFormat(cloud.utils.getNowInUTC8(now), "all")
    },
    cancelAddTime: false,
  });
}

//尾款退款
async function balanceRefund(pay, out_trade_no) {
  let out_refund_no = generateOrderNumber()
  const params = {
    out_trade_no,
    out_refund_no,//退款单号
    reason: '支付退款尾款',
    amount: {
      refund: data.balance_amount,
      total: data.balance_amount,
      currency: 'CNY',
    },
  };
  let result = await pay.refunds(params);
  console.log("尾款退款的结果", result);
  if (result.hasOwnProperty("errRaw")) {
    wxPayrecordError("refunds", result)
    return cloud.utils.requestReturn({ code: 500, msg: "退款失败，请检查是否有退款权限或余额是否足够" })
  } else {
    const ret = await pay.find_refunds(out_refund_no);
    console.log("查询尾款退款", ret);
    if (ret.status == "PROCESSING") {//退款成功
      await cloud.nw.db.update({
        dbName: "web-order",
        whereJson: { balance_out_trade_no: ret.out_trade_no }, //单号去查
        dataJson: { //更新订单
          balance_refund_info: {
            out_refund_no,
            refund_time: ret.create_time,
            refund_amount: ret.amount,  //单位是分，前端展示的时候要/100
            refund_id: ret.refund_id,
            transaction_id: ret.transaction_id,
            user_received_account: ret.user_received_account,
            updateUser: data.updateUser, //操作退款的人
            refundReason: data.refundReason,//退款原因
          },
        },
      });
      await changeOrderInfo({ balance_out_trade_no: ret.out_trade_no })
      await setOrderStatus({ balance_out_trade_no: ret.out_trade_no })
      return cloud.utils.requestReturn({ data: "退款成功" })
    } else {
      console.log("尾款退款失败", ret)
    }
  }
}


function generateOrderNumber() {
  const timestamp = Date.now().toString(); // 获取当前时间戳
  const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); // 生成3位随机数
  return timestamp + random; // 拼接时间戳和随机数作为订单号
}

function savePublicKey() {
  return `
-----BEGIN CERTIFICATE-----
MIIEKDCCAxCgAwIBAgIUNLJk3hYaWOL+VX9SbvbOxXRrZ3owDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjMwNzE5MDk0NjQ4WhcNMjgwNzE3MDk0NjQ4WjCBgTETMBEGA1UEAwwK
MTU5MzE1NDU4MTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQL
DCTkuIrmtbfkupror5rln7norq3lrabmoKHmnInpmZDlhazlj7gxCzAJBgNVBAYM
AkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAJ/auEoRpI0odU2LhVYPvOmo1wzc7c090vLEBHiJ73p4LMvO/HOlRjY7
LTfIDqqhZ9Xoqe9o3a6o1ameDTjVbXUxRkhHTtsrJdq5ql8rPVf7lolrmquWyI0/
f+vNKirEJO3JIq6h5Mbb+7tCmKlNnsvtHPL/qkjaBuvnd/uDEISt/IjYWxvOFJee
o55QMy+rbgTC0kKdiVKLenstG/jipPqXQw19lRjullf/RIntZ2xR9lA63E2li+tF
diC8ODrtjru1w+/R7WS+zQXLmvGTzaxAQDf5q+keN+yf7T5OvOtLmEoqI6UREN8J
kxXv0xN4kDfLIR0izbiD2xsMibYvXXMCAwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsG
A1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2Y2Eu
aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRC
MDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdB
OUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQAr6mQ7
8LJ1QvvTjMuMJ11UrgKf5wSawuJiL6MfetVBB51JwGKBfBJ/KgBsWrms+Eg38lZZ
QKDgwkLE/PfqEzB9NSjQkZvmpOfx6+KAXBAYrMngDwATIESgJAPFo4g/cowDpvaC
noNWvNHIZCR2whi29Zy8xoKONme944rYEYWFm1M06scglWuo2mo4Wk6/SiAVh6JO
91XJM0P+SxZV7CQ5K8aIpqUcppRk54MDujrLJB8lRVHUNWhcRzj7H6cMmfoY/H+a
CsocVeEBcwhbffZLaYhr7He60D3O2ADTZFRNr73dDb4zEDRrxhRjKHQDO7enUzc0
Vgj5ab17makmBtvs
-----END CERTIFICATE-----
`
}

function savePrivateKey() {
  const key = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf2rhKEaSNKHVN
i4VWD7zpqNcM3O3NPdLyxAR4ie96eCzLzvxzpUY2Oy03yA6qoWfV6KnvaN2uqNWp
ng041W11MUZIR07bKyXauapfKz1X+5aJa5qrlsiNP3/rzSoqxCTtySKuoeTG2/u7
QpipTZ7L7Rzy/6pI2gbr53f7gxCErfyI2FsbzhSXnqOeUDMvq24EwtJCnYlSi3p7
LRv44qT6l0MNfZUY7pZX/0SJ7WdsUfZQOtxNpYvrRXYgvDg67Y67tcPv0e1kvs0F
y5rxk82sQEA3+avpHjfsn+0+TrzrS5hKKiOlERDfCZMV79MTeJA3yyEdIs24g9sb
DIm2L11zAgMBAAECggEAZ76GXiPHHImGX7ZN6cW7ABZAwyta9hnKnx2SHTy//Eak
I/2In/FCeQ280ff3dMvd3Njr+OGhBaqzSCq4QAtbx3QcPepxhhIhtitLJAqm/EPe
tf7s2bG5JNpyRfHYDPtRUDV6WcXd+SVp4WVeOHqUtZqEcDx3ImLFnTKTDttHzCMs
J53W0nLQI3mZ0ADeua1DpEF3a2IrGTKRqIBxTHGlm5qniYCvpHImv+dTrcykq+Kx
0SSYLKYe3SstDsQUN+5jG0T1TIxm1Gwb9UW7AuK29YbTuE2T7Qa/T0AztAYZpbqK
5x7CnVhxFjFqugk2EpmE8/4nUBuXMuTP26KSyFLZ2QKBgQDNVXtlkXrRat5Xi/nO
VpErTTDwQbrMHsYQsh2EAYEQfnBLCDJ1V6dFx0IHrK3wkb4zMvkm2rWAwxdn81N+
mNzAwQU893Lh+Lv9x3DW70PvgE3XrvjqzGQW+f5eaiJlCjKgYJOC2pbcZCs+gXma
bc5xhIQUsxjzRSj1zl1bAVky5wKBgQDHTGO6S4VLKoaXuBAEX+IEvN8vWL7T4pW1
aXHb0UzZy+46bP87PghbNmCuqwM5h9DTQ4vRKhJV/+tmtYZR529x4wXlL7LJ6GED
rv5Iw2LxSshlLo/TwtHBt6rTxf//klh+XqUnNyXAd/0KAOp7GK/0c2w/y61Mrfd0
IuejBXq7lQKBgH4jeT6X9F8Zy6T0dG1xeJSlQt8VQe+LKBmxkbg6RFMhmVI+ouC7
DCMtmT6lseULY1CIi852pPGI56QQMsaemV5ANTuSt5xh9PqdvpALRCypISjScE+t
Z/9FbCIMCT0Q2rDzIytLpUmWr4oid9WKhzvtMEaXD0jCv7rhHzB8z5MZAoGAebgj
6HGbVQ8B6MOXtLRCvBYGUUpoMcxfFs7xpQktYI92TeSn9Syrudl6LvNvIsHaPk0w
pWyGilOlF7Oh93/bxriaryD0lu//4FoOH66FTU0ZGwLXAMQpi6B7CqAQ+6wLtBJl
14+M1QHzXxq0Gr43KJsd79CbZQuS6DExO5VrIgkCgYEAko7Lid52kjrDqLx2cSKc
Dsl8J2rBgzoFMD1E5bArbaBSt9zQ2DpS4PvkQYQxQ4SSg5v6CxYpcxLdpCA+fabI
eJpNNfuc3XxH5AOiO0u7s9pv+66aVbZP5t8NLI+PgnRwk4QPXLiO4soXgU6FEhsP
dv9KAEr9NLYadg0rMl09elc=
-----END PRIVATE KEY-----
`;
  return key;
}
